/*
 * @Author: zoufengfan
 * @Date: 2022-08-17 13:51:43
 * @LastEditTime: 2022-11-03 14:33:40
 * @LastEditors: zoufengfan
 */
import CustomerValueType from '@fc-rc/customer-value-type';
import type { FormInstance, ProFormColumnsType } from '@ant-design/pro-components';
import { BetaSchemaForm } from '@ant-design/pro-components';
import type { FormSchema } from '@ant-design/pro-components/node_modules/@ant-design/pro-form/lib/components/SchemaForm/typing';
import { Modal, Form, Spin, Button } from 'antd';
import type { Dispatch, SetStateAction, RefObject } from 'react';
import { useRef } from 'react';
import { useEffect } from 'react';
import React, { useCallback, useState, useImperativeHandle } from 'react';

type outPutRefs = {
  form: FormInstance;
};

export type Props<Item> = {
  /**定义子组件暴露的方法 */
  cRef?: RefObject<outPutRefs>;
  type: 'edit' | 'add';
  title: string;
  trigger?: JSX.Element;
  /** span: descriptionItem占的位置多少 colProps.span: formItem占的位置多少 */
  columns: ProFormColumnsType<Item, 'text'>[];
  /**发起网络请求的参数,返回值会覆盖给 initialValues */
  request?: () => Promise<Item>;
  onFinish: (
    /**表单值 */
    values: Item,
    /**closeModalFn()为关闭Modal */
    closeModalFn: () => void,
    /**unCloseModalFn()为不关闭Modal */
    unCloseModalFn: () => void,
  ) => void;
  BetaSchemaFormProps?: Partial<FormSchema<Item, 'text'>>;
  visible?: boolean;
  /**控制关闭 */
  visibleAction?: Dispatch<SetStateAction<boolean>>;
  /** 关闭前的提示文字 */
  closeConfirmText?: string;
  /** 提交前的提示文字 */
  finishConfirmText?: string;
};

function Add<Item>(props: Props<Item>) {
  const {
    cRef,
    type,
    trigger,
    title,
    columns,
    request,
    onFinish,
    BetaSchemaFormProps,
    visible,
    visibleAction,
    closeConfirmText,
    finishConfirmText,
  } = props;
  // 改_visible用于trigger控制的显示隐藏
  const [_visible, set_visible] = useState(false);
  const [loading, setloading] = useState(false);
  const [form]: [FormInstance<Item>] = Form.useForm<Item>();
  /**用于区分取消关闭按钮（cancel），和逻辑上的关闭（close） */
  const [closeType, setcloseType] = useState<'cancel' | 'close'>('close');

  // 暴露方法到外部
  useImperativeHandle(
    cRef,
    (): outPutRefs => ({
      form: form,
    }),
  );

  /**打开时触发 */
  const onVisibleChange = useCallback(
    (e: boolean) => {
      // console.log(e, closeType);
      set_visible(e);
      visibleAction?.(e);
      setTimeout(() => {
        BetaSchemaFormProps?.onVisibleChange?.(e);
      }, 0);
    },
    [BetaSchemaFormProps, visibleAction],
  );

  /**取消和x时触发 */
  const onCancel = useCallback(() => {
    // console.log('onCancel');
    setcloseType('cancel');
    Modal.confirm({
      title: '确认放弃操作？',
      content: closeConfirmText,
      onOk: (close) => {
        close();
        onVisibleChange(false);
      },
    });
  }, [closeConfirmText, onVisibleChange]);

  /**提交时 */
  const _onFinish = useCallback(
    (values: any) => {
      console.log('_onFinish', values as object);

      return new Promise<boolean>((res, rej) => {
        Modal.confirm({
          content: finishConfirmText || '是否提交?',
          onOk: (close: () => void) => {
            close();
            onFinish(
              values,
              () => {
                setcloseType('close');
                res(true); //会触发onVisibleChange
              },
              () => rej(false),
            );
          },
          onCancel: () => rej(false),
        });
      });
    },
    [finishConfirmText, onFinish],
  );

  // 请求初始值
  useEffect(() => {
    if (trigger && !_visible) return;
    if (!trigger && !visible) return;
    console.log('配置初始值', type, !!form.setFieldsValue);
    form.resetFields();
    if (type === 'edit' && request) {
      setloading(true);
      request()
        .then((res) => {
          console.log('edit res', res);
          // console.log('edit reset', form);

          form.setFieldsValue(res);
        })
        .catch((e) => {
          console.warn('edit req err', e);
        })
        .finally(() => {
          setloading(false);
        });
    }
  }, [form, request, type, _visible, trigger, visible]);

  return (
    <Spin spinning={loading}>
      <CustomerValueType>
        <BetaSchemaForm<Item>
          form={form}
          layoutType="ModalForm"
          trigger={trigger}
          visible={visible || _visible}
          layout="horizontal"
          rowProps={{ gutter: 16 }}
          grid={true}
          onFinish={_onFinish}
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 14 }}
          {...BetaSchemaFormProps}
          // layoutType有可能不为ModalForm
          modalProps={{
            onCancel,
            destroyOnClose: true,
            forceRender: true,
            width: 1000,
            title,
            maskClosable: false,
            okText: '提交',
            ...BetaSchemaFormProps?.modalProps,
          }}
          onVisibleChange={(e) => {
            console.log('add onVisibleChange', e);
            if (e) onVisibleChange(e);
            else if (!e && closeType === 'close') onVisibleChange(e);
          }}
          columns={columns}
        />
      </CustomerValueType>
    </Spin>
  );
}

export default Add;
